<?php
/**
  * DataType
  *
  * Base API for developing Data Types. All Data Types must be subclasses of this class
  *
  * @package Concerto
  * @subpackage Data Types
  * @author Jason Raede <jason@torchdm.com>
  */
 
namespace application\datatypes;

abstract class DataType {

	/**
	 * Name of the data type.
	 *
	 * @var string
	 */
	public static $name;
	
	/**
	 * Fields to add to the database for this datatype.
	 *
	 * Array is filled with bidimensional arrays with the following information:
	 * 'column'=> The (optional) string to add to the end of the column name for this particular column
	 *				(Only used if the data type has multiple database columns)
	 * 'columnType'=> The MySQL syntax for the column type, like VARCHAR(50) or FLOAT(10,6)
	 *
	 * @var array
	 */
	 
	public static $fields = array();
	
	/**
	 * Parameters used when displaying the data from the data type.
	 *
	 * An array of arrays with the following information:
	 * * 'label'=>Formatted name of the parameter
	 * * 'name'=>Name of the parameter as used in the display function
	 * * 'type'=>Type of input to generate with javascript. Can be "text", "select", "checkbox", "radio"
	 * * 'defaultValue'=>Optional default value for the parameter
	 * * 'options'=>Optional array of bidimensional arrays consisting of label/value pairs for select options
	 *
	 * @var array
	 * @see prepareData()
	 */
	public static $displayParams = array();
	
	/**
	 * Validates the data and formats it for database insertion
	 *
	 * Can add errors to the $results['errors'] array,
	 * or add data to the $results['db_fields'] array, with the index being the 
	 * column for insertion. End result looks like 
	 * $results['db_fields'][COLUMN_NAME] = COLUMN_DATA
	 *
	 * @see \application\models\ContentBase::fromDB()
	 * @see \application\models\ContentBase::getFormData()
	 * @param stdObject $field An object representing the field's row in the cn_content_fields table
	 * @param array $data The data associated with the current \application\models\Content object 
	 * @param array $results An array with the ['errors'] and ['db_fields'] array that is passed through
	 * 						The validation function of each data type associated with the content
	 * @return array $results The results array modified according to the validation process
	 */
	public static function validate($field, $data, $results) {}
	
	/**
	 * Displays the rendered form elements
	 *
	 * Form elements are generated by the build() function, and displayed with this function
	 *
	 * @see build()
	 * @param array $formElements An array of form element information from the build() function
	 */
	public static function display($formElements) {}
	
	/**
	 * Builds the form elements
	 *
	 * The form elements array is typically as follows, but can be structured anyway you want as long
	 * as the display() function knows how to use the information:
	 * * 'description'=>The field's description ($field->cf_description)
	 * * 'column'=>The field's column ($field->cf_column)
	 * * 'display'=>The field's display name ($field->cf_display_name)
	 * * 'data_type'=>The field's data type ($field->cf_data_type)
	 * * 'elements'=>Array of form elements, anatomy varies according to data type
	 *
	 * @see display()
	 * @param stdObject $field An object representing the field's row in cn_content_fields
	 * @param stdObject $row An object representing the content's row in cn_content and cn_content_typeX
	 * @return array An array of form elements using the format described above.
	 */
	public static function build($field, $row) {}
	
	/**
	 * Optional function for executing additional processes after the form has been submitted, validated,
	 * and the database row has been inserted or updated.
	 */
	public static function endForm() {}
	
	/**
	 * Optional function for when a content field that has this data type is deleted.
	 *
	 * Used for clearing out field meta or removing other database entries that are unique to the 
	 * data type.
	 */
	public static function delete() {}
	
	/**
	 * Optional function for adding content to the <head> tag in the form
	 *
	 * Used for including custom javascript, stylesheets, etc.
	 *
	 * @param stdObject $field An object representing the field's row in cn_content_fields
	 */
	public static function formHeader($field) {}
	
	/**
	 * Optional function for adding content to the <head> tag on the template
	 *
	 * Used for including custom javascript, stylesheets, etc. Note that this is only run
	 * when the engine knows that this content type is going to be displayed, so only on the plural
	 * and singular pages. Otherwise, you will have to manually execute this function in the <head>
	 * tags, if, say, you're running initQuery.
	 *
	 * @param stdObject $field An object representing the field's row in cn_content_fields
	 */
	public static function displayHeader($field) {}
	
	/**
	 * @deprecated
	 */
	public static function customHeader() {}
	
	/**
	 * Base function for converting information from the database into usable information
	 * for forms and display
	 *
	 * Essentially the opposite of validate(), which converts information from the form into
	 * database format.
	 *
	 * @see \application\models\ContentBase::fromDB()
	 * @see \application\models\ContentBase::getFormData()
	 * @see validate()
	 * @param array $fields An array of stdObjects, indexed by column name, of rows from cn_content_fields
	 * @param stdObject $field An object representing the current field's row from cn_content_fields
	 * @param array $data An array of current data on the content, for use in accessing other properties
	 * @return array An array of column (or subcolumn) - value pairs for use in the Data Type's internal processes
	 */
	public static function fromDB($fields, $field, $data) {
		$column = $field->cf_column;
		return array($field->cf_column => $fields[$column]);
	}
	
	/**
	 * Any custom handler for when a content field is added with this datatype
	 */
	public static function add() {}
	
	/**
	 * Any custom handler for when a content field is saved with this data type
	 */
	public static function save($field = null) {}
	
	/**
	 * Base function for preparing data for display in a template
	 *
	 * @param stdObject $field An object representing the current field's row from cn_content_fields
	 * @param array $data The data array on the content, with data from each field
	 * @param array $params An optional array of parameters for display, defined per data type
	 */
	public static function prepareData($field, $data, $params) {
		return $data[$field->cf_column];
	}
	
	/**
	 * Placeholder function for the data type's description.
	 *
	 * Used in the administration panel when hovering over a field's type
	 */
	public static function typeDescription() {
		echo 'This type has no description.';
	}
	
	/**
	 * Base function for the form used to edit a content field with this data type
	 *
	 * @param stdObject $field An object representing the current field's row from cn_content_fields
	 */
	public static function editForm($field) {
		?>
		<input type="hidden" name="field_id" value="<?=$field->getId()?>"/>
		<ul class="form-fields">
			<li>
				<label>Field Display Name</label>
				<input type="text" name="field_display_name" class="big wide" value="<?=$field->getDisplayName()?>"/>
			</li>
			<li>
				<label>Field Description</label>
				<textarea name="field_description" class="wide"><?=$field->getDescription()?></textarea>
			</li>
			<li>
				<label><input type="checkbox" name="field_required" <?=($field->getRequired()) ? 'checked="checked"' : ''?> value="1"/> Required</label>
				
			</li>
			
		</ul>
		<?php
	}
}
?>